﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using ReporterControlLibrary.Models;
using Reporter.Data;
using System.Windows.Input;
using Microsoft.Expression.Interactivity.Core;
using System.Windows.Data;
using System.Windows;
using Reporter.Controls;
using System.Windows.Media.Effects;
using ReporterControlLibrary.UIHelpers;
using ReporterEngine;
using ReporterSystem;
using Reporter.Converters;
using System.IO;

namespace Reporter.UIHelpers
{
    public class ApplicationManager
    {
        private Window _appWindow;

        public Window AppWindow
        {
            get { return _appWindow; }
            set { _appWindow = value; }
        }

        private UIElement _appWindowLayoutRoot;

        public UIElement AppWindowLayoutRoot
        {
            get { return _appWindowLayoutRoot; }
            set { _appWindowLayoutRoot = value; }
        }

        private BlurEffect _appBlurEffect;

        public BlurEffect AppBlurEffect
        {
            get
            {
                if (_appBlurEffect != null)
                {
                    return _appBlurEffect;
                }
                else
                {
                    _appBlurEffect = new BlurEffect();
                    _appBlurEffect.KernelType = KernelType.Gaussian;
                    _appBlurEffect.Radius = 2;
                    _appBlurEffect.RenderingBias = RenderingBias.Performance;
                    return _appBlurEffect;
                }
            }
            set { _appBlurEffect = value; }
        }

        #region Commands

        public ICommand AddProjectTemplateCommmand
        {
            get;
            private set;
        }

        public ICommand DeleteProjectTemplateCommand
        {
            get;
            private set;
        }

        public ICommand CreateNewProjectCommmand
        {
            get;
            private set;
        }

        public ICommand DeleteProjectCommmand
        {
            get;
            private set;
        }

        public ICommand OpenProjectCommmand
        {
            get;
            private set;
        }

        public ICommand PublishProjectCommmand
        {
            get;
            private set;
        }

        public ICommand OpenTeamProjectCommmand
        {
            get;
            private set;
        }

        public ICommand CloseProjectCommand
        {
            get;
            private set;
        }

        public ICommand CloseAllProjectsCommand
        {
            get;
            private set;
        }

        public ICommand BrowseProjectTemplateCommand
        {
            get;
            private set;
        }

        public ICommand ImportProvisionNotebookCommand
        {
            get;
            private set;
        }

        public ICommand OpenTemplateCommand
        {
            get;
            private set;
        }

        public ICommand OpenResultCommand
        {
            get;
            private set;
        }

        public ICommand SetTemplateParametersCommand
        {
            get;
            private set;
        }

        public ICommand StartReportingCommand
        {
            get;
            private set;
        }


        public ICommand EvaluatePathCommand
        {
            get;
            private set;
        }

        public ICommand EvaluatePathTabSelectedCommand
        {
            get;
            private set;
        }

        public ICommand BrowseModelTabSelectedCommand
        {
            get;
            private set;
        }

        public ICommand EvalModelExpandedCommand
        {
            get;
            private set;
        }

        public ICommand EvalModelCollapsedCommand
        {
            get;
            private set;
        }

        public ICommand ModelTreeSelectedItemChangedCommand
        {
            get;
            private set;
        }

        #endregion

        #region Properties

        public static ObservableCollection<IProject> Projects
        {
            get { return AppData.Projects; }
        }

        #endregion

        #region Constructors

        public ApplicationManager()
        {
            this.AddProjectTemplateCommmand = new ActionCommand(this.AddPojectTemplate);
            this.DeleteProjectTemplateCommand = new ActionCommand(this.DeleteProjectTemplate);
            this.CreateNewProjectCommmand = new ActionCommand(this.CreatePoject);
            this.DeleteProjectCommmand = new ActionCommand(this.DeleteProject);
            this.OpenProjectCommmand = new ActionCommand(this.OpenProject);
            this.OpenTeamProjectCommmand = new ActionCommand(this.OpenTeamProject);
            this.PublishProjectCommmand = new ActionCommand(this.PublishProject);
            this.CloseProjectCommand = new ActionCommand(this.CloseProject);
            this.CloseAllProjectsCommand = new ActionCommand(this.CloseAllProjects);
            this.BrowseProjectTemplateCommand = new ActionCommand(this.BrowseProjectTemplate);
            this.ImportProvisionNotebookCommand = new ActionCommand(this.ImportProvisionNotebook);
            this.OpenTemplateCommand = new ActionCommand(this.OpenTemplate);
            this.OpenResultCommand = new ActionCommand(this.OpenResult);
            this.StartReportingCommand = new ActionCommand(this.StartReporting);
            this.EvaluatePathCommand = new ActionCommand(this.EvaluatePath);
            this.EvaluatePathTabSelectedCommand = new ActionCommand(this.EvaluatePathSelected);
            this.BrowseModelTabSelectedCommand = new ActionCommand(this.BrowseModelSelected);
            this.EvalModelExpandedCommand = new ActionCommand(this.EvalModelExpanded);
            this.EvalModelCollapsedCommand = new ActionCommand(this.EvalModelCollapsed);
            this.ModelTreeSelectedItemChangedCommand = new ActionCommand(this.ModelTreeSelectedItemChanged);
            this.SetTemplateParametersCommand = new ActionCommand(this.SetTemplateParameters);

            ReportApp.OnUpdateTemplate += new BoolMessageHandler(ReportApp_OnUpdateTemplate);

            david.EvalDocasny += new EventHandler(david_EvalDocasny);
        }

        bool ReportApp_OnUpdateTemplate(string message)
        {

            this._appWindow.Dispatcher.Invoke(new Action(
                                    () =>
                                    {
                                        var dlgProp = ReporterControlLibrary.MessageBox.Show(this._appWindow,
                                               "Server contains updated version of " + message + " template. ...Update... ?",
                                               "Provision Reporter",
                                               MessageBoxButton.YesNo,
                                               MessageBoxImage.Question);
                                    }
                                    ), null);

            //var dlg = ReporterControlLibrary.MessageBox.Show(this._appWindow,
            //    "Server contains updated version of " + message + " template. ...Update... ?",
            //    "Provision Reporter",
            //    MessageBoxButton.YesNo,
            //    MessageBoxImage.Question);

            //switch (dlg.Result)
            //{
            //    case MessageBoxResult.Yes:
            //        return true;
            //    case MessageBoxResult.No:
            //        return false;
            //}

            return false;
        }

        void david_EvalDocasny(object sender, EventArgs e)
        {
            var project = sender as Project;
            Evaluate(project);
        }

        #endregion

        #region Methods

        private void AddPojectTemplate(object selectedItem)
        {
            if (selectedItem is Project)
                AppData.CreateNewReportInfo(selectedItem as Project);
            else if (selectedItem is ReportInfo)
                AppData.CreateNewReportInfo((selectedItem as ReportInfo).Project);

        }

        private void DeleteProjectTemplate(object selectedReportInfo)
        {
            var ri = selectedReportInfo as ReportInfo;
            if (ri != null)
            {
                // Configure the message box to be displayed
                string messageBoxText = "Do you want to delete project template \"" + ri.TemplateName + "\" ?";

                ActivateAppBlurEffect();

                var dlg = ReporterControlLibrary.MessageBox.Show(this._appWindow, messageBoxText, "Provision Reporter", MessageBoxButton.YesNo, MessageBoxImage.Warning);

                DeactivateAppBlurEffect();

                //// Process message box results
                switch (dlg.Result)
                {
                    case MessageBoxResult.Yes:
                        //TODO: validate logic before delete

                        //delete data
                        ReportApp.DeleteTemplate(ri.ReportTemplate, ri.Project.ReportProject);

                        //delete from design
                        ri.Project.ReportInfos.Remove(ri);


                        break;
                    case MessageBoxResult.No:
                        // User pressed No button
                        // ...
                        break;
                }
            }
        }

        private void BrowseProjectTemplate(object selectedReportInfo)
        {
            var ri = selectedReportInfo as ReportInfo;
            if (ri != null)
            {
                // Configure open file dialog box
                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
                dlg.Filter = "Text documents (.docx)|*.docx"; // Filter files by extension

                // Show open file dialog box
                Nullable<bool> result = dlg.ShowDialog();

                // Process open file dialog box results
                if (result == true)
                {
                    //ri.TemplateFile = dlg.FileName;

                    var templatePath = ReportApp.GetTemplatePath(ri.Project.ReportProject, ri.ReportTemplate);
                    File.Copy(dlg.FileName, templatePath,true);

                    //ri.ResultName = ri.TemplateName = (System.IO.Path.GetFileNameWithoutExtension(dlg.SafeFileName));
                }
            }
        }

        private void SetTemplateParameters(object selectedReportInfo)
        {
            var ri = selectedReportInfo as ReportInfo;
            if (ri != null)
            {
                //select parameters from actual template
                var templateXDoc = ReportApp.GetTemplateDocumetContent(ri.ReportTemplate, ri.Project.ReportProject);

                var template = Template.Parse(templateXDoc.Root);

                var parameters = template.GetParameters();

                bool hasChanges = false;
                //set parameters to template and refresh
                foreach(var paramName in parameters)
                {
                    var paramTest = ri.ReportParameters.Where(x => x.Name == paramName).FirstOrDefault();
                    if(paramTest == null)
                        ri.ReportParameters.Add(new ReportParameter{Name = paramName});

                    //add param to template and save project
                    var paramTemplate = ri.ReportTemplate.Parameters.Where(x => x.ParameterName == paramName).FirstOrDefault();
                    
                    if(paramTemplate == null)
                    {
                        hasChanges = true;
                        ri.ReportTemplate.Parameters.Add(new TemplateParameter{ParameterName = paramName});
                    }
                }

                if(hasChanges)
                    ReportApp.UpdateProjectInfo(ri.Project.ReportProject);

                ReportInfoParametersDialogBox dlg = new ReportInfoParametersDialogBox(ri);

                ActivateAppBlurEffect();

                dlg.Owner = _appWindow;
                dlg.ShowDialog();
                DeactivateAppBlurEffect();

                if (dlg.DialogResult == true)
                {
                    //iterate all params and values
                    hasChanges = false;

                    foreach(var parameter in ri.ReportParameters)
                    {
                        var paramTemplate = ri.ReportTemplate.Parameters.Where(x => x.ParameterName == parameter.Name).FirstOrDefault();
                        if (paramTemplate.Value != parameter.Value)
                        {
                            paramTemplate.Value = parameter.Value;
                            hasChanges = true;
                        }
                    }

                    if (hasChanges)
                        ReportApp.UpdateProjectInfo(ri.Project.ReportProject);
                }
            }
        }

        private void ImportProvisionNotebook(object parameters)
        {
            var p = parameters as ImportNotebookParameter;
            if (p != null)
            {
                ImportProvisionNotebookDialogBox dlg = new ImportProvisionNotebookDialogBox();

                ActivateAppBlurEffect();

                dlg.Project = p.Project;
                dlg.ImportImages = p.ImportImages;

                dlg.Owner = _appWindow;
                dlg.ShowDialog();


                DeactivateAppBlurEffect();
            }
        }

        private void CreatePoject()
        {
            NewProjectDialogBox dlg = new NewProjectDialogBox();

            // Configure the dialog box
            // dlg.Owner = this;

            ActivateAppBlurEffect();

            dlg.Owner = _appWindow;
            dlg.ShowDialog();

            if (dlg.DialogResult == true)
            {
                //TODO: replace Project info with model class
                var pInfo = dlg.ProjectInfo;

                var reportProject = new ReportProject();
                reportProject.Name = pInfo.Project.Name;
                //TODO: associate all parameters

                ReportApp.CreateReportProject(reportProject);

                //reportapp create project
                AppData.AddProject(reportProject);
            }
            DeactivateAppBlurEffect();
        }

        private void DeleteProject(object selecteditem)
        {
            var project = selecteditem as Project;

            //TODO: Implement deletion of project - data

            if (project == null)
            {
                var lcv = selecteditem as ListCollectionView;
                if (lcv != null)
                    project = lcv.CurrentItem as Project;
            }



            if (project != null)
            {
                // Configure the message box to be displayed
                string messageBoxText = "Do you want to delete project \"" + project.Name + "\" ?";

                ActivateAppBlurEffect();
                var dlg = ReporterControlLibrary.MessageBox.Show(this._appWindow, messageBoxText, "Provision Reporter", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                DeactivateAppBlurEffect();

                if (dlg.Result == MessageBoxResult.Yes)
                {
                    AppData.RemoveProject(project);
                    ReportApp.DeleteReportProject(project.ReportProject);
                }
            }
        }

        private void OpenProject()
        {
            // Configure open file dialog box
            var dlg = new Microsoft.Win32.OpenFileDialog
                          {
                              Filter = "Text documents (.preportinfo)|*.preportinfo",
                              InitialDirectory = ReportApp.MyDocumentsFolder
                          };

            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results
            if (result == true)
            {
                AppData.LoadProject(dlg.FileName);
            }
        }

        private void OpenTeamProject()
        {
            //TODO: implement import of project from webservice   
        }

        private void PublishProject(object selectedProject)
        {
            var project = selectedProject as Project;

            PublishProjectDialogBox dlg = new PublishProjectDialogBox();

            dlg.Project = project;

            dlg.Owner = _appWindow;
            dlg.ShowDialog();

            if (dlg.DialogResult == true)
            {
               
            } 
        }

        private void OpenTemplate(object selecteditem)
        {
            var reportInfo = selecteditem as ReportInfo; // Implementovat otvorenie salony v MS Word
            //TODO verify file
            var templatePath = ReportApp.GetTemplatePath(reportInfo.Project.ReportProject, reportInfo.ReportTemplate);
            try
            {
                Process.Start(templatePath);
            }
            catch (Exception)
            {
                //TODO move text to resources
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Template does not exists", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void OpenResult(object selecteditem)
        {
            OpenDocument(selecteditem);
        }

        private void OpenDocument(object selecteditem)
        {
            var reportInfo = selecteditem as ReportInfo;// Implementovat otvorenie salony v MS Word
            //TODO verify file
            var resultPath = ReportApp.GetResultPath(reportInfo.Project.ReportProject, reportInfo.ReportTemplate);

            try
            {
                Process.Start(resultPath);
            }
            catch (Exception)
            {
                //TODO move text to resources
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Report does not exists", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            int ee = 12;
        }

        private void EvaluatePath(object selectedProject)
        {
            //var project = selectedProject as Project;

           // Evaluate(project);
        }

        private void EvaluatePathSelected(object selectedProject)
        {
            var project = selectedProject as Project;

            var cifFile = ReportApp.GetCifPath(project.ReportProject);

            if (!File.Exists(cifFile))
            {
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Cif Model does not exists. Import notebook ... please", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (project.MetaModel.EvalResult == null)
            {
                Task.Factory.StartNew(() =>
                {
                    var model = ReportApp.GetModel(project.ReportProject);

                    project.MetaModel.EvalResult = model.GetInstanceCategories();
                });
            }
        }

        private void BrowseModelSelected(object selectedProject)
        {
            //bind data to model if empty
            var project = selectedProject as Project;

            if(project == null) return;

            var cifFile = ReportApp.GetCifPath(project.ReportProject);

            if (!File.Exists(cifFile))
            {
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Cif Model does not exists. Import notebook ... please", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if(project.MetaModel.Instances == null)
            {
                Task.Factory.StartNew(() =>
                                          {
                                              var model = ReportApp.GetModel(project.ReportProject);

                                              project.MetaModel.Instances = model.GetInstanceCategories();
                                          });
            }
        }

        private void StartReporting(object selecteditem)
        {
            var reportInfo = selecteditem as ReportInfo;

            if (reportInfo == null) return;

            

            // implementuj reportovanie ....
            var tempReportID = reportInfo.ReportTemplate.ReportTemplateID;

            var tmpMessageInfo = AppData.GetReportInfoByID(tempReportID);

            ReportSettingsArgs messageSettings = new ReportSettingsArgs
            {
                TemplatePath = ReportApp.GetTemplatePath(tmpMessageInfo.Project.ReportProject, tmpMessageInfo.ReportTemplate),
                ResultPath = ReportApp.GetResultPath(tmpMessageInfo.Project.ReportProject, tmpMessageInfo.ReportTemplate),
                ModelPath = ReportApp.GetCifPath(tmpMessageInfo.Project.ReportProject),
                ExportPath = ReportApp.GetExportPath(tmpMessageInfo.Project.ReportProject),
                ProjectName =  tmpMessageInfo.Project.ReportProject.Name,
                TemplateName = tmpMessageInfo.ReportTemplate.TemplateFileName,
                ResultName = tmpMessageInfo.ReportTemplate.ResultFileName
            };

            //Validate paths
            if (!File.Exists(messageSettings.TemplatePath))
            {
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Template does not exists", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            
            FileInfo f = new FileInfo(messageSettings.TemplatePath);

            if (f.Length == 0)
            {
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Template file is empty", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (!File.Exists(messageSettings.ModelPath))
            {
                ReporterControlLibrary.MessageBox.Show(this._appWindow, "Cif Model does not exists. Import notebook ... please", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            //if result is used by other app show message

            if (File.Exists(messageSettings.ResultPath))
            {
                FileInfo fres = new FileInfo(messageSettings.ResultPath);

                try
                {
                    using (var str = File.OpenWrite(messageSettings.ResultPath))
                    {}
                }
                catch (IOException)
                {

                    ReporterControlLibrary.MessageBox.Show(this._appWindow, "Result file is open in other application. Please close report file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
               
            }

            //show progress bar
            reportInfo.IsReporting = true;
            reportInfo.ReportLogs.Clear();

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                                             (object o) =>
                                                 {
                                                    // var testint = int.Parse("dasd");
                                                 
                                                 var reportid = tempReportID;
                                                 var currentStatusInt = 0;

                                                 var currentMessagesCount = 0;

                                                 //initialize data fore report instances
                                                 var tmpInfo = AppData.GetReportInfoByID(reportid);

                                                 ReportManager target = new ReportManager();

                                                 ReportSettingsArgs settings = new ReportSettingsArgs
                                                 {
                                                     TemplatePath = ReportApp.GetTemplatePath(tmpInfo.Project.ReportProject, tmpInfo.ReportTemplate),
                                                     ResultPath = ReportApp.GetResultPath(tmpInfo.Project.ReportProject, tmpInfo.ReportTemplate),
                                                     ModelPath = ReportApp.GetCifPath(tmpInfo.Project.ReportProject),
                                                     ExportPath = ReportApp.GetExportPath(tmpInfo.Project.ReportProject),
                                                     ProjectName = tmpInfo.Project.ReportProject.Name,
                                                     ResultName = tmpInfo.ReportTemplate.ResultFileName,
                                                     TemplateName = tmpInfo.ReportTemplate.TemplateFileName
                                                 };

                                                 foreach(var parameter in tmpInfo.ReportParameters)
                                                 {
                                                     settings.Parameters.Add(parameter.Name, parameter.Value);

                                                 }

                                                 //run timer

                                                 Timer timer = new System.Threading.Timer(new TimerCallback(delegate(object sender)
                                                                                                                {

                                                                                                                    this._appWindow.Dispatcher.Invoke(new Action(
                                                                                                                                                          () =>
                                                                                                                                                          {
                                                                                                                                                              var localReportInfo = AppData.GetReportInfoByID(reportid);

                                                                                                                                                              if (localReportInfo != null)
                                                                                                                                                              {
                                                                                                                                                                  localReportInfo.FinishedPercentage = currentStatusInt;

                                                                                                                                                                  UpdateMessages(localReportInfo, ref currentMessagesCount, settings);
                                                                                                                                                              }
                                                                                                                                                          }
                                                                                                                                                          ), null);
                                                                                                                }
                                                                                              ), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(200));


                                                 //run report

                                                

                                                 target.Report(settings);

                                                 //for (int i = 0; i <= 100; i++)
                                                 //{
                                                 //    currentStatusInt = i;

                                                 //    Thread.Sleep(100);
                                                 //}

                                                 //stop timer

                                                 timer.Dispose();

                                                 //end of counting)
                                                 this._appWindow.Dispatcher.Invoke(new Action(
                                                                                       () =>
                                                                                       {
                                                                                           var localReportInfo = AppData.GetReportInfoByID(reportid);

                                                                                           if (localReportInfo != null)
                                                                                           {
                                                                                               //update messages
                                                                                               UpdateMessages(localReportInfo, ref currentMessagesCount, settings);



                                                                                               localReportInfo.ReportTemplate.ReportedDate = DateTime.Now;
                                                                                               //update report
                                                                                               ReportApp.UpdateProjectInfo(localReportInfo.Project.ReportProject);

                                                                                               localReportInfo.LastReportDate = localReportInfo.ReportTemplate.ReportedDate;

                                                                                               localReportInfo.IsReporting = false;
                                                                                               localReportInfo.FinishedPercentage = -1;
                                                                                               localReportInfo.LastReportDate =DateTime.Now;

                                                                                               if (localReportInfo.AutoOpenResult)
                                                                                                   OpenDocument(localReportInfo);
                                                                                           }
                                                                                       }
                                                                                       ), null);
                                              
                                             }
                                             ));

        }

        private static void UpdateMessages(ReportInfo localReportInfo, ref int currentMessagesCount, ReportSettingsArgs settings)
        {
            if(currentMessagesCount < settings.Messages.Count)
            {
                foreach(var messageLog in settings.Messages.ToList().Skip(currentMessagesCount))
                {
                    var mType = 2;

                    if (messageLog.MessageLogType == MessageLogTypes.Error)
                        mType = 0;
                    if (messageLog.MessageLogType == MessageLogTypes.Warning)
                        mType = 1;
                                                                                                                                                                          
                    localReportInfo.ReportLogs.Add(new ReportLog{
                                                                    Message = messageLog.Message,
                                                                    Type = mType
                                                                });
                }

                currentMessagesCount = settings.Messages.Count;
            }
        }

        private void CloseProject(object selecteditem)
        {
            var project = selecteditem as Project;

            if (project != null)
                AppData.RemoveProject(project);
            else
            {
                var lcv = selecteditem as ListCollectionView;

                if (lcv != null && lcv.CurrentItem is Project)
                {
                    AppData.RemoveProject((Project)lcv.CurrentItem);
                }
            }
        }

        private void EvalModelExpanded(object selecteditem)
        {
            var ri = selecteditem as ReportInfo;

            if (ri == null) return;

//            const string content = @"  {section: >> test >> orderby(id, 'name' desc, 'description')} 
//                                            {text >> description} 
//                                            {text: >> test1}
//                                            {text: >> test1}
//                                            {text: >> test1}
//                                            {section :>> test2}
//                                                {text: >> test1}
//                                                {text: >> test1}
//                                                {textik: >> test1}
//                                                {section : name2 >> test2}
//                                                    {text: >> test1}
//                                                {endsection}
//                                            {endsection}
//                                        {endsection}";

            var content = ReportApp.GetTemplateDocumetContent(ri.ReportTemplate, ri.Project.ReportProject);

            ri.TemplateTreeSource = ReporterEngine.Template.Parse(content.Root);

            ri.TemplateTreeInstancesSource = null;
        }

        public static void Evaluate(Project Project)
        {
            var model = ReportApp.GetModel(Project.ReportProject);

            sQuery query = sQuery.New(model);
            query.Elements.Add(model.Notebook);


            var actualPath = LexPath.Scan(Project.MetaModel.EvalExpression);
            Interpreter target = Interpreter.Create(actualPath);

            var actual = target.Execute(actualPath, query);
            //show eerors and log

            Project.MetaModel.ErrorMessage = null;

            if (actual.HasError)
            {
                Project.MetaModel.ErrorMessage = actual.ErrorMessage.ToString();
                
                Project.MetaModel.ModelStructure = null;
                Project.MetaModel.EvalResult = null;
            }
            else
            {
                if(actual.Elements.Count == 0)
                {
                    Project.MetaModel.ErrorMessage = "No Results matching Expression.";
                }

                var tres = model.GetInstanceCategories(actual);

                Project.MetaModel.EvalResult = tres;
                //}
                var am = new AvailableModel();
                // am.ModelProperties = new ObservableCollection<ModelProperty> { new ModelProperty { Name = "popery 1" }, new ModelProperty { Name = "popery 2" }, new ModelProperty { Name = "popery 3" } };
                // am.ModelReferences = new ObservableCollection<ModelReference> { new ModelReference { Name = "reference 1" }, new ModelReference { Name = "reference 2" }, new ModelReference { Name = "reference 3" } };
                // am.ModelUsedBys = new ObservableCollection<ModelUsedBy> { new ModelUsedBy { Name = "object 1" }, new ModelUsedBy { Name = "object 2" }, new ModelUsedBy { Name = "object 3" } };
                // am.ModelMethods = new ObservableCollection<ModelMethod> { new ModelMethod { Name = "function 1", Description = "This si sample decription of method functionalities 1  ..." }, new ModelMethod { Name = "function 2", Description = "This si sample decription of method functionalities 2 ..." }, new ModelMethod { Name = "function 3", Description = "This si sample decription of method functionalities 3 ..." } };
                am.ModelStoredExpressions = new ObservableCollection<ModelStoredExpression> {new ModelStoredExpression() {Name = "(Activity) << Core, Start, End", ShortDescription = "Select all Core, Start, End ...", Description = "This si sample decription of stored expression  ..."}};
                //am.ModelTypes = new ObservableCollection<ModelType> { new ModelType { Name = "type 1" }, new ModelType { Name = "type 2" }, new ModelType { Name = "type 3" } };





                if (am.ModelMethods == null)
                    am.ModelMethods = new ObservableCollection<ModelMethod>();

                am.ModelMethods.Clear();
                foreach (var modelType in Interpreter.GetAvailableMethods(query))
                {
                    am.ModelMethods.Add(modelType);
                }




                if (am.ModelTypes == null)
                    am.ModelTypes = new ObservableCollection<ModelType>();

                am.ModelTypes.Clear();
                foreach (var modelType in actual._model.GetModelTypes(actual).Take(10))
                {
                    am.ModelTypes.Add(modelType);
                }

                if (am.ModelProperties == null)
                    am.ModelProperties = new ObservableCollection<ModelProperty> {new ModelProperty {Name = "id"}, new ModelProperty {Name = "name"}, new ModelProperty {Name = "type"}};

                am.ModelProperties.Clear();
                am.ModelProperties.Add(new ModelProperty {Name = "id"});
                am.ModelProperties.Add(new ModelProperty {Name = "name"});
                am.ModelProperties.Add(new ModelProperty {Name = "type"});
                foreach (var modelType in actual._model.GetModelproperties(actual).Take(10))
                {
                    am.ModelProperties.Add(modelType);
                }

                if (am.ModelReferences == null)
                    am.ModelReferences = new ObservableCollection<ModelReference>();

                am.ModelReferences.Clear();
                foreach (var modelType in actual._model.GetModelreferencies(actual).Take(10))
                {
                    am.ModelReferences.Add(modelType);
                }

                if (am.ModelUsedBys == null)
                    am.ModelUsedBys = new ObservableCollection<ModelUsedBy>();

                am.ModelUsedBys.Clear();
                foreach (var modelType in actual._model.GetModelUsedBy(actual).Take(10))
                {
                    am.ModelUsedBys.Add(modelType);
                }

                Project.MetaModel.ModelStructure = am;
            }
        }

        private void EvalModelCollapsed(object selecteditem)
        {
            var ri = selecteditem as ReportInfo;

            if (ri == null) return;

            ri.TemplateTreeSource = null;
            ri.TemplateTreeInstancesSource = null;
        }

        private void ModelTreeSelectedItemChanged(object selecteditem)
        {
        }
       
        private void CloseAllProjects()
        {
            AppData.RemoveAllProjects();
        }

        private void ActivateAppBlurEffect()
        {
            if (AppWindow is IShadeableWindow)
                ((IShadeableWindow)AppWindow).ActivateWindowShade();
            // ActivateBlurEffect(_appWindowLayoutRoot);
        }

        private void DeactivateAppBlurEffect()
        {
            if (AppWindow is IShadeableWindow)
                ((IShadeableWindow)AppWindow).DeactivateWindowShade();
            // DeactivateBlurEffect(_appWindowLayoutRoot);
        }

        private void ActivateBlurEffect(UIElement element)
        {
            if (element != null)
                element.Effect = this.AppBlurEffect;
        }

        private void DeactivateBlurEffect(UIElement element)
        {
            if (element != null)
                element.Effect = null;
        }

        #endregion


    }


}
